﻿using System.Linq;
using CID.Domain.Infrastructure;
using CID.Tests.Support;
using NUnit.Framework;

namespace CID.Domain.Persistence.Tests.Infrastructure
{
    [TestFixture]
    class TemplatePersistenceTests : BasePersistenceWithDataTests
    {
        private static void AssertAreEqual(Template expected, Template actual)
        {
            Assert.AreEqual(expected.Id, actual.Id);
            Assert.AreEqual(expected.Name, actual.Name);
            Assert.AreEqual(expected.Description, actual.Description);
            Assert.AreEqual(expected.Enabled, actual.Enabled);
            Assert.AreEqual(expected.MultipleServersSupport, actual.MultipleServersSupport);
            Assert.AreEqual(expected.Content, actual.Content);
            Assert.AreEqual(expected.Type.Id, actual.Type.Id);
            CollectionAssert.AreEquivalent(expected.Parameters.Select(x => x.Id), actual.Parameters.Select(x => x.Id));
        }

        [Test]
        public void SaveNewTemplate_TemplateShouldBeSaved()
        {
            var session = OpenSession();
            var newTemplate = DataProvider.CreateActivationTemplate(session, InfrastructureData.TemplateType);
            session.SaveOrUpdate(newTemplate);
            CleanSession(session);

            Assert.AreNotEqual(NotSavedId, newTemplate.Id);
            session = OpenSession();
            var retrievedTemplate = session.Get<Template>(newTemplate.Id);
            AssertAreEqual(newTemplate, retrievedTemplate);
            CleanSession(session);
        }

        [Test]
        public void SaveModifiedTemplate_ChangesShouldBeSaved()
        {
            var session = OpenSession();
            var newTemplate = DataProvider.CreateActivationTemplate(session, InfrastructureData.TemplateType);
            session.SaveOrUpdate(newTemplate);
            var newParameter = newTemplate.CreateParameter(GetRandomString(), GetRandomString(), ParameterType.Decimal);
            CleanSession(session);

            session = OpenSession();
            var modifiedTemplate = session.Get<Template>(newTemplate.Id);
            AssertAreEqual(newTemplate, modifiedTemplate); //Necessary to load lazy collections before the session is wiped out
            modifiedTemplate.ModifyProperty(x => x.Name);
            modifiedTemplate.ModifyProperty(x => x.Description);
            modifiedTemplate.CreateParameter(GetRandomString(), GetRandomString(), ParameterType.DateTime);
            modifiedTemplate.RemoveParameter(DataProvider.GetParameter(session, newParameter));
            modifiedTemplate.ModifyProperty(x => x.Enabled);
            modifiedTemplate.ModifyProperty(x => x.MultipleServersSupport);
            session.SaveOrUpdate(modifiedTemplate);
            CleanSession(session);

            session = OpenSession();
            var retrievedTemplate = session.Get<Template>(newTemplate.Id);
            AssertAreEqual(modifiedTemplate, retrievedTemplate);
            CleanSession(session);
        }

        [Test]
        public void DeleteTemplate_TemplateShouldBeDeleted()
        {
            var session = OpenSession();
            var newTemplate1 = DataProvider.CreateActivationTemplate(session, InfrastructureData.TemplateType, "Another Template");
            var newTemplate2 = DataProvider.CreateActivationTemplate(session, InfrastructureData.TemplateType);
            session.SaveOrUpdate(newTemplate1);
            session.SaveOrUpdate(newTemplate2);
            CleanSession(session);

            session = OpenSession();
            var retrievedTemplate1 = session.Get<Template>(newTemplate1.Id);
            session.Delete(retrievedTemplate1);
            CleanSession(session);

            session = OpenSession();
            retrievedTemplate1 = session.Get<Template>(newTemplate1.Id);
            var retrievedTemplate2 = session.Get<Template>(newTemplate2.Id);
            Assert.IsNull(retrievedTemplate1);
            Assert.IsNotNull(retrievedTemplate2);
            CleanSession(session);
        }
    }
}
